package vip.xiaonuo.biz.modular.detect.service.utils;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import vip.xiaonuo.biz.modular.detect.entity.BizDetectImageParam;
import vip.xiaonuo.biz.modular.detect.entity.PythonDetectResult;
import vip.xiaonuo.biz.modular.detect.service.BizDetectService;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
//定义websocket服务器端，它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址
@ServerEndpoint(value = "/ws/detect")
@Slf4j
public class DetectWebSocket {
    private static ConcurrentHashMap<String, DetectWebSocket> requestToSocketMap = new ConcurrentHashMap<>();
    //实例一个session，这个session是websocket的session
    private Session session;

    //存放websocket的集合
    private static CopyOnWriteArraySet<DetectWebSocket> detectWebSocketSet = new CopyOnWriteArraySet<>();

    //将请求id和Websocket会话联系起来
    public void registerRequest(String requestId, DetectWebSocket socket) {
        requestToSocketMap.put(requestId, socket);
    }

    //根据请求id查找对应的Websocket会话
    public static DetectWebSocket findWebSocketByRequestId(String requestId) {
        return requestToSocketMap.get(requestId);
    }

    // 新增取消注册请求ID的方法
    public static void unregisterRequest(String requestId) {
        requestToSocketMap.remove(requestId);
    }

    //前端请求时一个websocket时
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        detectWebSocketSet.add(this);
        log.info("【websocket消息】有新的连接, 总数:{}", detectWebSocketSet.size());
    }

    //前端关闭时一个websocket时
    @OnClose
    public void onClose() {
        detectWebSocketSet.remove(this);
        log.info("【websocket消息】连接断开, 总数:{}", detectWebSocketSet.size());
    }

    //前端向后端发送消息
    @OnMessage
    public void onMessage(String message, Session session) {
        ApplicationContext act = ApplicationContextRegister.getApplicationContext();
        BizDetectService detectService = act.getBean(BizDetectService.class);
        log.info("【websocket消息】收到客户端发来的消息:{}", message);

        BizDetectImageParam bizDetectImageParam = JSONUtil.toBean(message, BizDetectImageParam.class);
        String requestId = RandomUtil.randomString(8);; // 生成唯一请求ID
        bizDetectImageParam.setRequestId(requestId);
        // 关联请求ID与WebSocket会话
        registerRequest(requestId, this);
        detectService.detect(bizDetectImageParam);
    }
    //@OnMessage
    //public void onMessage(String message) {
    //    ApplicationContext act = ApplicationContextRegister.getApplicationContext();
    //    BizDetectService detectService = act.getBean(BizDetectService.class);
    //    log.info("【websocket消息】收到客户端发来的消息:{}", message);
    //    BizDetectImageParam bizDetectImageParam = JSONUtil.toBean(message, BizDetectImageParam.class);
    //    detectService.detect(bizDetectImageParam);
    //}

    //新增一个方法用于主动向客户端发送消息
    public void sendMessage(PythonDetectResult pythonDetectResult) {
        String requestId = pythonDetectResult.getRequestId();
        log.info("开始寻找特定客户端... ...");
        DetectWebSocket targetSocket = findWebSocketByRequestId(requestId);
        if (targetSocket != null) {
            try {
                log.info("已经找到特定客户端... ...");
                log.info("【websocket消息】发送到特定客户端, message={}，{}", pythonDetectResult.getResult(),pythonDetectResult.getPath());
                targetSocket.session.getBasicRemote().sendText(JSONUtil.toJsonStr(pythonDetectResult));
                //targetSocket.session.getBasicRemote().sendText(pythonDetectResult.getPath());
                unregisterRequest(requestId);
            } catch (Exception e) {
                log.error("发送结果到WebSocket时发生异常", e);
            }

        } else {
            log.warn("未能找到与requestId {} 对应的WebSocket会话", requestId);
        }
    }
}
